package com.cskaoyan.javase.oop1._6constructor._0introduction;

/**
 * 构造器的引入
 * 引例
 * 创建一个教师类，有课程和年龄两个属性，行为是可以上课。
 * 现在我们需要创建以下对象：
 * 18岁的Java老师对象
 * 28岁的C++老师对象
 * 30岁的Python老师对象
 * ...
 * 按照之前我们的做法，需要先创建出对象，再进行成员变量的赋值。
 * 这样做如果只有一个两个对象还好，如果需要创建很多对象，就有点过于麻烦了。
 * 对象的属性，能不能"出厂"的时候就设定好呢？
 * 有这种需求时，就需要，构造方法（constructor，也叫构造器）来完成了。
 *
 * 这里我们需要一种"灵活的,在创建对象过程中给成员变量赋值"的手段
 * 这种手段就是构造器
 *
 * 构造器的语法:
 * 构造器(constructor,也叫构造方法)需要写在一个类的类体中,它是一个特殊的方法
 * [访问权限修饰符] 类名(形参列表){
 *   // 构造方法体
 * }
 * 解释:
 * 1.访问权限修饰符我们还没有学习，这里我们默认它是public修饰的。
 * 2.类名,实际上就是构造器的名字,它必须和当前类的类名完全一致。
 * （类名是大驼峰的，这里也要大驼峰）
 * 3.形参列表可以为空，称之为无参构造方法，简称无参构造。
 *      当然也可以有参数，是为有参构造。
 *      一个类中是允许存在多个构造器的,要求形参列表不同,它们构成方法重载的关系
 * 4.构造方法是没有返回值的,也没有返回值类型,更不能在方法体中用"return".
 *
 *
 * 类中构造器的作用:
 *      1,构造器的作用是创建对象过程中,给成员变量赋值.
 *      2.在Java代码中使用new关键字创建对象，必然调用该类构造方法。构造器的作用是用来给成员变量赋值的。
 *      构造器的调用不是程序员去完成的,而是在创建对象过程中,由JVM自动调用该方法
 *      实际上程序员也没有办法直接调用该方法
 *      但是程序员仍然能够指定,JVM调用哪个构造方法,来完成成员变量的赋值.
 *      语法:
 *          new 类名(实参列表);
 *      由于类中构造器可能存在方法重载,所以根据实参列表来具体决定调用哪个方法
 *
 *
 * 构造器的具体定义/调用:
 *      昨天我们根据以下语法来创建Student对象:
 *      Student s = new Student();
 *      这里调用的是Student类的无参构造方法.
 *
 * 1.实际上,我们并没有在类中直接手动定义无参构造器,但是仍然能够调用无参构造器.原因是因为:
 *      Java的任何类中,如果该类没有手动的,直接的提供某个构造器
 *      那么就提供一个默认的,无参构造器
 *      默认的无参构造器,语法结构是:
 *      public 类名(){}
 *      默认无参显然是不能完成成员变量赋值的,所以
 *      想要赋值,必须提供有参构造器
 *
 *
 * 2.有参构造器,可以在创建对象过程中,灵活的给成员变量赋值
 * 标准语法结构是:
 * public 类名(数据类型 成员变量1,数据类型 成员变量2..){
 *      this.成员变量1 = 成员变量1;
 *      ...
 * }
 * 在构造器/构造方法中,也隐含了this关键字,指向当前对象,这一点和成员方法是类似的,this的使用也是类似的
 *
 * 3.一个类中可以出现多个构造器,组成方法的重载.
 *
 *
 * @since 09:44
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        t.course = "JavaSE";
        t.age = 18;

        Teacher t2 = new Teacher();
        t2.course = "C++";
        t2.age = 28;

        Teacher t3 = new Teacher();
        t3.course = "Python";
        t3.age = 30;

        // 测试使用有参构造器
        Teacher t4 = new Teacher(18);
        System.out.println(t4.age);

        // 测试双参构造器
        Teacher t5 = new Teacher("数学", 48);
        System.out.println(t5.age);
        System.out.println(t5.course);
    }
}

class Teacher {
    String course;
    int age;

    public void teach() {
        System.out.println("这位老师教授" + course);
    }

    // 默认无参
    public Teacher() {
    }

    // 有参构造器,用于给age赋值
    public Teacher(int age) {
        this.age = age;
    }

    // 双参构造器
    public Teacher(String course, int age) {
        this.course = course;
        this.age = age;
    }
}